//
// Created by Symps on 2025/9/14.
//

#ifndef TEST25_6_14_QUEUE_H
#define TEST25_6_14_QUEUE_H

#include <iostream>
#include <stdexcept>
#include "ListNode.h"

using namespace std;

template<typename T>
class Queue {
    friend ostream &operator<<(ostream &out, const Queue<T> &queue) {
        out << "[";
        auto curr = queue._front;
        if (curr) {
            for (; curr->_next; curr = curr->_next) {
                out << curr->_value << ", ";
            }
            out << curr->_value;
        }
        out << "]";
        return out;
    }

public:
    using Node = ListNode<T>;

    Queue() : _front(nullptr), _rear(nullptr) {}

    Queue(const Queue& queue) : _front(nullptr), _rear(nullptr) {
        for (auto curr = queue._front; curr; curr = curr->_next) {
            enqueue(curr->_value);
        }
    }

    ~Queue() {
        clear();
    }

    void enqueue(T value) {
        if (_front) {
            _rear = _rear->_next = new Node(value);
        } else {
            _front = _rear = new Node(value);
        }
    }

    void dequeue() {
        if (_front) {
            Node *temp = _front;
            _front = _front->_next;
            delete temp;
        } else {
            throw std::runtime_error("Queue is empty");
        }
    }

    void clear() {
        while (_front) {
            dequeue();
        }
    }

    Queue& operator=(const Queue& queue) {
        if (this != &queue) {
            clear();
            for (auto curr = _front; curr; curr = curr->_next) {
                enqueue(curr->_value);
            }
        }
        return *this;
    }

    [[nodiscard]] bool empty() const {
        return _front == nullptr;
    }

    [[nodiscard]] T front() const {
        if (_front) {
            return _front->_value;
        } else {
            throw std::runtime_error("Queue is empty");
        }
    }

    [[nodiscard]] T rear() const {
        if (_rear) {
            return _rear->_value;
        } else {
            throw std::runtime_error("Queue is empty");
        }
    }
private:
    Node *_front;
    Node *_rear;
};


#endif //TEST25_6_14_QUEUE_H
